package conn

import (
	"db2s/Dm"
	"db2s/Gr"
	sqlserver "db2s/Ms"
	"db2s/My"
	"db2s/Or"
	"db2s/ref"
	"errors"
	"fmt"
	"reflect"
	"strings"
	"time"
)

type ConText struct {
	Name     string
	Device   string        `json:"device"`
	Jdbc     string        `json:"jdbc"`
	MaxIdle  int           `json:"maxIdle"`
	MaxOpen  int           `json:"maxOpen"`
	IdleTime time.Duration `json:"idleTime"`
	LeftTime time.Duration `json:"leftTime"`
	Mode     string        `json:"mode"`
}

var (
	driveMap = func(name string) any {
		switch name {
		case "mysql":
			return My.NewConnObject()
		case "oracle":
			return Or.NewConnObject()
		case "greatdb":
			return Gr.NewConnObject()
		case "sqlserver":
			return sqlserver.NewConnObject()
		case "dm":
			return Dm.NewConnObject()
		}
		return nil
	}
)

func driveCheck(name string) (e any, err error) {
	e = driveMap(name)
	if e == nil {
		err = errors.New(fmt.Sprintf("input database type error. input is {%v} What is expected is {%v}", name, func() string {
			var p []string
			//for k := range driveMap {
			//	p = append(p, k)
			//}
			return strings.Join(p, ",")
		}()))
	}
	return
}

func NewConn(drive string) (res ConEr, err error) {
	var e any
	var event = "[NewConn]"
	if e, err = driveCheck(drive); err != nil {
		err = ref.ErrAddPrintf(event, err)
		return
	}
	switch e.(type) {
	case My.Conn:
		res = e.(My.Conn)
	case Dm.Conn:
		res = e.(Dm.Conn)
	case Gr.Conn:
		res = e.(Gr.Conn)
	case Or.Conn:
		res = e.(Or.Conn)
	case sqlserver.Conn:
		res = e.(sqlserver.Conn)
	default:
		err = ref.ErrAddPrintf(event, errors.New(fmt.Sprintf("type not matched. curry type is %v", reflect.TypeOf(e))))
		return
	}
	return
}
